package com.apexsoft.assets.base.utils;

import com.apexsoft.assets.base.exception.ValidException;
import com.apexsoft.assets.base.request.DataJSONRequest;
import com.apexsoft.assets.base.request.ListJSONRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.lang.reflect.Field;
import java.util.Set;

/**
 * Created by Administrator on 2018/3/21.
 */
public class ValidatorUtil {
    private static final ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
    private static final Logger LOG = LoggerFactory.getLogger(ValidatorUtil.class);

    public static <T> boolean validate(T value) throws ValidException {
        if (null == value) {
            return true;
        }
        ValidException validException = new ValidException(null);
        validateInner(value, validException, "");
        if (value instanceof DataJSONRequest) {
            Object data = ((DataJSONRequest) value).getData();
            validateInner(data, validException, "data.");
        }
        if (value instanceof ListJSONRequest) {
            Object data = ((ListJSONRequest) value).getData();
            validateInner(data, validException, "data.");
        }
        Field[] fields = value.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (!field.getClass().getName().startsWith("java.lang")) {
                try {
                    field.setAccessible(true);
                    Object fieldValue = field.get(value);
                    validateInner(fieldValue, validException, field.getName() + ".");
                } catch (IllegalAccessException e) {
                    LOG.warn("格式校验异常" + e.getMessage(), e);
                } finally {
                    field.setAccessible(false);
                }
            }

        }
        if (validException.getError().size() > 0) {
            throw validException;
        }
        return true;
    }

    private static void validateInner(Object data, ValidException validException, String preField) {
        if (data != null) {
            Validator validator = vf.getValidator();
            Set<ConstraintViolation<Object>> result = validator.validate(data);
            if (result.size() > 0) {
                for (ConstraintViolation<Object> constraintViolation : result) {
                    validException.setParamError(preField + constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
                }
            }
        }
    }
}
